package com.drawu.drawuspring.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.drawu.drawuspring.domain.DTO.ActivitiesDto;
import com.drawu.drawuspring.domain.DTO.PostDTO;
import com.drawu.drawuspring.domain.Result;
import com.drawu.drawuspring.domain.VO.*;
import com.drawu.drawuspring.domain.po.*;
import com.drawu.drawuspring.enums.AppHttpCodeEnum;
import com.drawu.drawuspring.mapper.ActivitiesMapper;
import com.drawu.drawuspring.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.drawu.drawuspring.utils.AppThreadLocalUtil;
import com.drawu.drawuspring.utils.BeanUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.drawu.drawuspring.utils.Coze.runWorkflow1;
import static com.drawu.drawuspring.utils.Coze.runWorkflowCommon;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hui
 * @since 2025-04-01
 */
@Service
@RequiredArgsConstructor
public class ActivitiesServiceImpl extends ServiceImpl<ActivitiesMapper, Activities> implements IActivitiesService {

    private final IActCommentsService actCommentsService;
    private final IParticipantsService participantsService;
    private final IGameInfoService gameInfoService;
    private final IUsersService usersService;
    private final ICommentsService commentsService;
    private final IForumService forumService;
    private final IImagesService imagesService;

    @Override
    public Result createActivity(ActivitiesDto dto) {
        Users user = AppThreadLocalUtil.getUser();
        if (user == null) {
            return Result.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        Activities activity = BeanUtils.copyBean(dto, Activities.class);
        activity.setOrganizer(user.getId());
//        String gameId = dto.getGameId();
//        String[] gameIds = gameId.split(",");
        List<Integer> userIds = dto.getUserIds();
        boolean save = this.save(activity);
        if (userIds != null && userIds.size() > 0) {
            participantsService.savePat(userIds, activity.getId());
        }
        if (save) {
            return Result.success();
        } else {
            return Result.fail("活动创建失败");
        }
    }

    @Override
    public Result updateActivity(ActivitiesDto dto) {
        Activities activity = BeanUtils.copyBean(dto, Activities.class);
        boolean update = this.updateById(activity);
        if (update) {
            return Result.success();
        } else {
            return Result.fail("活动更新失败");
        }
    }

    @Override
    @Transactional
    public Result deleteActivity(Long id) {
        boolean remove = this.removeById(id);
        actCommentsService.removeByActId(id);
        participantsService.removeByActId(id);
        if (remove) {
            return Result.success();
        } else {
            return Result.fail("活动删除失败");
        }
    }

    @Override
    public ActivitiesVo queryActivity(Long id) {
        Activities activity = this.getById(id);
        if (activity == null) {
            return null;
        }
        ActivitiesVo vo = BeanUtil.copyProperties(activity, ActivitiesVo.class);
        List<ActComments> actComments = actCommentsService.queryByActId(id);
        List<Participants> participants = participantsService.queryByActId(id);
        List<ParticipantVo> participantVoList = BeanUtils.copyList(participants, ParticipantVo.class);
        for (ParticipantVo participantVo : participantVoList) {
            Users user = usersService.getById(participantVo.getUserId());
            UserVO userVO = BeanUtils.copyBean(user, UserVO.class);
            participantVo.setUser(userVO);
        }
        String gameId = activity.getGameId();
        String[] gameIds = gameId.split(",");
        List<GameInfo> gameInfos = gameInfoService.listByIds(Arrays.asList(gameIds));
        Users organizer = usersService.getById(activity.getOrganizer());
        UserVO organizerVO = BeanUtils.copyBean(organizer, UserVO.class);
        UserVO userVOResult = usersService.getUser().getData();
        Boolean isJoin = participantsService.count(new QueryWrapper<Participants>()
                .eq("activity_id", id)
                .eq("user_id", userVOResult.getId())) > 0 || userVOResult.getId() == activity.getOrganizer();
        vo.setIsJoined(isJoin);
        vo.setUserVo(organizerVO);
        vo.setGameInfo(gameInfos);
        vo.setActCommentsList(actComments);
        vo.setParticipantVoList(participantVoList);
        return vo;
    }

    @Override
    public Result joinActivity(Long activityId, Integer userId) {
        Activities activities = this.getById(activityId);
        if (activities == null) {
            return Result.fail("活动不存在");
        }
        Participants participants = new Participants();
        participants.setActivityId(Math.toIntExact(activityId));
        participants.setUserId(userId);
        boolean save = participantsService.save(participants);
        if (save) {
            return Result.success();
        } else {
            return Result.fail("参与活动失败");
        }
    }

    @Override
    public Result quitActivity(Long activityId, Integer userId) {
        Activities activities = this.getById(activityId);
        if (activities == null) {
            return Result.fail("活动不存在");
        }
        boolean remove = participantsService.removeByActIdAndUserId(activityId, userId);
        if (remove) {
            return Result.success();
        } else {
            return Result.fail("退出活动失败");
        }
    }

    @Override
    public Result queryAllActivities() {
        //查询未结束的活动所有活动
        QueryWrapper<Activities> queryWrapperr = new QueryWrapper<>();
        queryWrapperr.gt("end_time", new Date());
        List<Activities> activities = this.list(queryWrapperr);
        if (activities == null) {
            return Result.fail("活动不存在");
        }
        List<ActivitiesVo> vos = BeanUtils.copyList(activities, ActivitiesVo.class);
        Set<Integer> userIds = vos.stream().map(ActivitiesVo::getOrganizer).filter(Objects::nonNull).collect(Collectors.toSet());
        List<Users> usersList = usersService.listByIds(userIds);
        if (usersList == null || usersList.size() == 0) {
            return Result.fail("活动不存在");
        }
        Map<Integer, UserVO> userVOMap = usersList.stream().collect(Collectors.toMap(Users::getId, user -> BeanUtils.copyBean(user, UserVO.class)));
        Set<Integer> artids = activities.stream().map(Activities::getId).filter(Objects::nonNull).collect(Collectors.toSet());
        QueryWrapper<Participants> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("activity_id", artids);
        List<Participants> participants = participantsService.list(queryWrapper);
        Set<Integer> parsUserIds = participants.stream().map(Participants::getUserId).filter(Objects::nonNull).collect(Collectors.toSet());
        List<Users> parsUsersList = usersService.listByIds(parsUserIds);
        Map<Integer, UserVO> parsUserVOMap = parsUsersList.stream().collect(Collectors.toMap(Users::getId, user -> BeanUtils.copyBean(user, UserVO.class)));
        Map<Integer, List<Participants>> participantsMap = participants.stream().collect(Collectors.groupingBy(Participants::getActivityId));
        List<ActComments> actComments = actCommentsService.listByIds(artids);
        Map<Integer, List<ActComments>> actCommentsMap = actComments.stream().collect(Collectors.groupingBy(ActComments::getActivityId));
        List<String> gameIds = activities.stream().map(Activities::getGameId).filter(Objects::nonNull).collect(Collectors.toList());

        for (ActivitiesVo vo : vos) {
            vo.setUserVo(userVOMap.get(vo.getOrganizer()));//组织者
            List<Participants> pars = participantsMap.get(vo.getId());
            List<ParticipantVo> parsVoList = BeanUtils.copyList(pars, ParticipantVo.class);
            for (ParticipantVo parsVo : parsVoList) {
                parsVo.setUser(parsUserVOMap.get(parsVo.getUserId()));
            }
            vo.setParticipantVoList(parsVoList);//参与者
            vo.setActCommentsList(actCommentsMap.get(vo.getId()));//评论
            String gameId = vo.getGameId();
            String[] split = gameId.split(",");
            List<GameInfo> gameInfos = gameInfoService.listByIds(Arrays.asList(split));
            vo.setGameInfo(gameInfos);
        }
        return Result.success(vos);
    }

    @Override
    public Result queryUserActivities() {
        Users users = AppThreadLocalUtil.getUser();
        // 查询当前用户创建的活动id 或 参与的活动id
        // 参与的活动
        QueryWrapper<Participants> partQueryWrapper = new QueryWrapper<>();
        partQueryWrapper.eq("user_id", users.getId());
        List<Integer> actIds = participantsService.list(partQueryWrapper).stream().map(Participants::getActivityId).collect(Collectors.toList());
        // 合并参与的活动id和创建的活动id
        QueryWrapper<Activities> orgQueryWrapper = new QueryWrapper<>();
        orgQueryWrapper.in("id", actIds).or().eq("organizer", users.getId());
        List<Activities> activities = this.list(orgQueryWrapper);
        if (activities == null) {
            return Result.fail("活动不存在");
        }
        List<ActivitiesVo> vos = BeanUtils.copyList(activities, ActivitiesVo.class);
        Set<Integer> artids = activities.stream().map(Activities::getId).filter(Objects::nonNull).collect(Collectors.toSet());
        List<Integer> artidss = participantsService.queryByActId();
        artids.addAll(artidss);
        QueryWrapper<Participants> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("activity_id", artids);
        List<Participants> participants = participantsService.list(queryWrapper);
        Set<Integer> parsUserIds = participants.stream().map(Participants::getUserId).filter(Objects::nonNull).collect(Collectors.toSet());
        if (parsUserIds != null && parsUserIds.size() > 0) {
            List<Users> parsUsersList = usersService.listByIds(parsUserIds);
            Map<Integer, UserVO> parsUserVOMap = parsUsersList.stream().collect(Collectors.toMap(Users::getId, user -> BeanUtils.copyBean(user, UserVO.class)));
            Map<Integer, List<Participants>> participantsMap = participants.stream().collect(Collectors.groupingBy(Participants::getActivityId));
            for (ActivitiesVo vo : vos) {
                List<Participants> pars = participantsMap.get(vo.getId());
                List<ParticipantVo> parsVoList = BeanUtils.copyList(pars, ParticipantVo.class);
                for (ParticipantVo parsVo : parsVoList) {
                    parsVo.setUser(parsUserVOMap.get(parsVo.getUserId()));
                }
                vo.setParticipantVoList(parsVoList);//参与者
                String gameId = vo.getGameId();
                String[] split = gameId.split(",");
                List<GameInfo> gameInfos = gameInfoService.listByIds(Arrays.asList(split));
                vo.setGameInfo(gameInfos);
            }
        }
        return Result.success(vos);

    }

    @Override
    public Result aiFill(ActivitiesDto dto) throws Exception {
        // 预设参数
        String prompt = "帮我想一个桌游活动名，";
        if (dto.getTitle() != null && !dto.getTitle().isEmpty()) {
            prompt += "主题是" + dto.getTitle() + "，";
        }
        int minPeopNum = 2;
        if (dto.getGameId() != null && !dto.getGameId().isEmpty()) {
            String[] split = dto.getGameId().split(",");
            List<GameInfo> gameInfos = gameInfoService.listByIds(Arrays.asList(split));
            String gameNames = gameInfos.stream().map(GameInfo::getName).collect(Collectors.joining("、"));
            for (GameInfo gameInfo : gameInfos) {
                int peopNum = Integer.parseInt(gameInfo.getPlayers().substring(0, 1));
                if (peopNum > minPeopNum) {
                    minPeopNum = peopNum;
                }
            }
            prompt += "活动桌游是" + gameNames + "，活动名可以带上活动桌游";
        }
        if (dto.getPeopNum() != null && dto.getPeopNum() > 0) {
            int peopNum = dto.getPeopNum();
            if (minPeopNum > peopNum) {
                peopNum = minPeopNum;
            }
            prompt += "参加活动的人数" + peopNum + "人，";
        }
        if (dto.getAddress() != null && !dto.getLocationName().isEmpty()) {
            prompt += "活动地点是" + dto.getAddress() + "，";
        }
        prompt += "活动名要简单明了有趣，让大家容易记住。";
        System.out.println(prompt);
        JSONObject jsonObject = runWorkflow1(prompt, "7493374758340509708");
        // 解析结果
        AiFillActivityVo result = new AiFillActivityVo();
        JSONObject output = (JSONObject) jsonObject.get("output");
        result.setTitle(output.get("title").toString());
        result.setContent(output.get("content").toString());
        if (dto.getGameId() == null || dto.getGameId().isEmpty()) {
            String games = "1,2";
            String[] split = games.split(",");
            List<GameInfo> gameInfos = gameInfoService.listByIds(Arrays.asList(split));
            result.setGameList(gameInfos);
            minPeopNum = 2;
            result.setPeopNum(minPeopNum);
        }

        return Result.success(result);
    }

    @Override
    public Result activityWithGame(Integer gameId) {
        if (gameId == null) {
            return Result.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // activities的game_id字段是一个字符串,里面包含了多个gameId，用逗号分割，如"1,2,3"，也可能是单个gameId，如"1"
        // 需要分割成数组，然后查询里面gameId等于数组中某个元素的活动
        QueryWrapper<Activities> queryWrapper = new QueryWrapper<>();
        queryWrapper.likeRight("game_id", "," + gameId + ",").or().eq("game_id", gameId).or().likeRight("game_id", "," + gameId);
        queryWrapper.gt("end_time", new Date());
        List<Activities> activities = this.list(queryWrapper);
        if (activities == null) {
            return Result.fail("活动不存在");
        }
        List<ActivitiesVo> vos = BeanUtils.copyList(activities, ActivitiesVo.class);
        Set<Integer> artids = activities.stream().map(Activities::getId).filter(Objects::nonNull).collect(Collectors.toSet());
        List<Integer> artidss = participantsService.queryByActId();
        artids.addAll(artidss);
        QueryWrapper<Participants> parQueryWrapper = new QueryWrapper<>();
        queryWrapper.eq("activity_id", artids);
        List<Participants> participants = participantsService.list(parQueryWrapper);
        Set<Integer> parsUserIds = participants.stream().map(Participants::getUserId).filter(Objects::nonNull).collect(Collectors.toSet());
        if (parsUserIds != null && parsUserIds.size() > 0) {
            List<Users> parsUsersList = usersService.listByIds(parsUserIds);
            Map<Integer, UserVO> parsUserVOMap = parsUsersList.stream().collect(Collectors.toMap(Users::getId, user -> BeanUtils.copyBean(user, UserVO.class)));
            Map<Integer, List<Participants>> participantsMap = participants.stream().collect(Collectors.groupingBy(Participants::getActivityId));
            for (ActivitiesVo vo : vos) {
                List<Participants> pars = participantsMap.get(vo.getId());
                List<ParticipantVo> parsVoList = BeanUtils.copyList(pars, ParticipantVo.class);
                for (ParticipantVo parsVo : parsVoList) {
                    parsVo.setUser(parsUserVOMap.get(parsVo.getUserId()));
                }
                vo.setParticipantVoList(parsVoList);//参与者
                String gameIds = vo.getGameId();
                String[] split = gameIds.split(",");
                List<GameInfo> gameInfos = gameInfoService.listByIds(Arrays.asList(split));
                vo.setGameInfo(gameInfos);
            }
        }
        return Result.success(vos);
    }

    public Result generateReport(Integer activityId) throws Exception {
        if (activityId == null) {
            return Result.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // **** 处理以下内容成BoardgameReportVo ****
        // 获取活动信息
        ActivitiesVo actVo = this.queryActivity(Long.valueOf(activityId));
        if (actVo == null) {
            return Result.fail("活动不存在");
        }

        // 获取用户信息
        Integer userId = AppThreadLocalUtil.getUser().getId();
        Users user = usersService.getById(userId);
        String nickname = user.getNickname();

        // 获取活动发布者、参与者信息
        List<Integer> parsUserIds = actVo.getParticipantVoList().stream().map(ParticipantVo::getUserId).collect(Collectors.toList());
        parsUserIds.add(actVo.getUserVo().getId());
        List<String> actUserNameList = usersService.listByIds(parsUserIds).stream().map(u -> u.getNickname()).collect(Collectors.toList());
        Integer peopNum = actUserNameList.size();

        // 获取帖子评论
        List<CommentVO> actComments = commentsService.getCommentsByPostId(2, activityId);
        // 获取评论用户信息
        List<BoardgameReportCommentVo> comments = actComments.stream().map(comment -> {
            BoardgameReportCommentVo vo = new BoardgameReportCommentVo();
            vo.setNickname(comment.getUserVO().getNickname());
            vo.setContent(comment.getContent());
            vo.setUrl(comment.getUrl());
            vo.setCreateTime(comment.getCreateTime());
            return vo;
        }).collect(Collectors.toList());

        // 打包用户信息 参与活动者信息 活动信息 评论信息 桌游信息
        BoardgameReportVo boardgameReportVo = BeanUtils.copyBean(actVo, BoardgameReportVo.class);
        boardgameReportVo.setNickname(nickname);
        boardgameReportVo.setActUserNameList(actUserNameList);
        boardgameReportVo.setTime(actVo.getStartTime().toString() + "-" + actVo.getEndTime().toString());
        boardgameReportVo.setPeopNum(peopNum);
        boardgameReportVo.setGamesName(actVo.getGameInfo().stream().map(GameInfo::getName).collect(Collectors.joining(",")));
        boardgameReportVo.setComments(comments);

        // 发送给AI
        String workflowId = "7496737939641778191";
        // 将boardgameReportVo转换为Map
        Map<String, Object> input = new HashMap<>();
        BeanUtils.copyProperties(boardgameReportVo, input);
        // 调用Coze工作流
        JSONObject jsonObject = runWorkflowCommon(workflowId, input);

        // **** 生成文章 ****
        PostDTO postDTO = new PostDTO();
        postDTO.setTitle(jsonObject.getString("title"));
        postDTO.setContent(jsonObject.getString("content"));
        postDTO.setArea("桌游战报");
        List<String> images = comments.stream().map(BoardgameReportCommentVo::getUrl).filter(url -> url != null && !url.isEmpty()).collect(Collectors.toList());
        postDTO.setImages(images);
        postDTO.setUserId(userId);
        Posts boardgameReport = forumService.createPost(postDTO);

        // **** 生成 ****
        return Result.success(boardgameReport);
    }
}


